/*********************************************************************************
 *      Copyright:  (C) 2022 YanlinZhou<1222>
 *                  All rights reserved.
 *
 *       Filename:  msqt_client.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(04/18/2022)
 *         Author:  YanlinZhou <1222>
 *      ChangeLog:  1, Release initial version on "04/18/2022 08:20:38 PM"
 *                 
 ********************************************************************************/

#include "main.h"			

/* Command line parameter parsing struct */
struct option opts[]= 
{
	{ "time",   	required_argument, NULL, 't' },
	{ "platform",   required_argument, NULL, 'p' },
	{ "deamon",		no_argument,	   NULL, 'd' },
	{ "help",   	no_argument,       NULL, 'h' },
	{0, 0, 0, 0}
};

int main(int argc, char **argv)
{
	char       			*progname = basename(argv[0]);
	float				temp = 66.66;	// store sample temperature
	int					rv = -1;

	app_ctx_t 			app_ctx;

	app_ctx.debug = 0;
	app_ctx.my_daemon = 0;
	app_ctx.time_ctx.tv = 0;
	app_ctx.time_ctx.last_time = 0;
	app_ctx.time_ctx.sample_interval = 0;

	while( (rv = getopt_long(argc, argv, "t:p:dh", opts, NULL)) != -1 ) 
	{
		switch(rv) 
		{
			case 't': 
				app_ctx.time_ctx.sample_interval = atoi(optarg); 
				break;

			case 'p': 
				app_ctx.mqtt_ctx.platform = atoi(optarg); 
				break;

			case 'd': 
				app_ctx.my_daemon = 1; 
				app_ctx.debug = 0;  
				break;

			case 'h': 
				print_client_usage(argv[0]); 
				return 0;
		}

	}

	if(!app_ctx.time_ctx.sample_interval || !app_ctx.mqtt_ctx.platform)
	{
		print_client_usage(argv[0]);
		return -1;
	}	

	printf ("****************************************\n\n");
	printf ("****** The program start to run! *******\n\n");
	printf ("****************************************\n\n");

	if( init_config_total(&app_ctx) < 0 )
	{
		log_error("init_config_mqtt failure!\n");
		return -1;
	}
	sleep(1);

	while(!g_stop)
	{
		/* Determine whether the sampling time is reached */
		if(determin_time(&app_ctx.time_ctx))
		{
			/* sample time is arrival */
			printf("\n\n");
			printf("************************************\n");
			printf("sample time is arrival!\n");

			/* sample temperature */
			if(get_temperature(&temp)<0)
			{
				log_error("get_temperature failure!\n");
				continue;
			}

			app_ctx.pack_ctx.payload = temp;
			printf("get_temperature successful:%f\n", temp);
			
			/* Package data in JSON format */
			if( pack_in_json(&app_ctx.pack_ctx, &app_ctx.time_ctx, app_ctx.mqtt_ctx) != 0 )
			{
				log_error("pack_in_json failure!\n");
				continue;
			}

			log_debug("str:\n %s \n", app_ctx.pack_ctx.str);

			/* mosquitto_init */
			if( mosquitto_init(&app_ctx.mqtt_ctx) <0 )
			{
				log_error("mosquitto_init function call failure!\n");

				/* save the data into the database */
				if( (rv = client_save_data(app_ctx.sqlite_ctx, temp, ctime(&app_ctx.time_ctx.tv))) < 0 ) 
				{
					log_error(  "client_save_data failure:%s",strerror(errno));
					continue;
				}

				log_info("save data into database successfully at : %s\n", ctime(&app_ctx.time_ctx.tv));
				continue;
			
			}

			/* post data（ successful：contnnue ; failure：Put the data into the database and reconnect）*/
			else
       		{
				if( mosquitto_publish(app_ctx.mqtt_ctx.mosq, NULL, app_ctx.mqtt_ctx.topic, strlen(app_ctx.pack_ctx.str), app_ctx.pack_ctx.str, 0, 0) != MOSQ_ERR_SUCCESS )
           		{
					log_info("public failure will save the data into database and  reconnecting! \n");

					/* save the data into the database */
					if( (rv = client_save_data(app_ctx.sqlite_ctx, temp, ctime(&app_ctx.time_ctx.tv))) < 0 ) 
					{
						log_error(  "client_save_data failure:%s",strerror(errno));
						goto CleanUp;
					}

					log_info("save data into database successfully at : %s\n", ctime(&app_ctx.time_ctx.tv));
					goto CleanUp;
        		}

        	log_info("public function call successfully\n");
			printf("public data to cloud paltform successfully at  %s\n", ctime(&app_ctx.time_ctx.tv));
			printf ("*********************************************************************\n\n");

			}
		
		}

		else /* If the sampling time is not reached, check whether data exists in the database */
		{
			if( (rv = inquire_first_row_msqt(&app_ctx.sqlite_ctx,  &app_ctx.pack_ctx, &app_ctx.time_ctx)) <0 )
			{   
				log_error("inquire_first_row function call select first row failure%s\n");
				continue; 
			}   

			else if( 1==rv ) 
			{   
				log_debug("the database have data\n");

				/* pack the data from database and send the data */
	            if( pack_in_json(&app_ctx.pack_ctx, &app_ctx.time_ctx, app_ctx.mqtt_ctx) != 0 ) 
				{
					log_error("pack_in_json failure!\n");
					continue;
				}

	            log_debug("str  from database :\n %s \n", app_ctx.pack_ctx.str);

				/* mosquitto_init */
				if( mosquitto_init(&app_ctx.mqtt_ctx) <0 )
				{
					log_error("mosquitto_init function call failure!\n");
					continue;
				}

				if( mosquitto_publish(app_ctx.mqtt_ctx.mosq, NULL, app_ctx.mqtt_ctx.topic, strlen(app_ctx.pack_ctx.str), app_ctx.pack_ctx.str, 0, 0) != MOSQ_ERR_SUCCESS )
				{
					log_error("publish database data failure!");
					goto CleanUp;
				}

				log_info("Client public database table's first record  sucessfully at %s\n", ctime(&app_ctx.time_ctx.tv));

			 	/*  delete database first row */
			 	if( delete_db_first_record(app_ctx.sqlite_ctx) <0 )
				{
					 log_debug("delete_db_first_record failure:%s\n", strerror(errno));
					 goto CleanUp;
				}

				log_info("Client delete database table's first record  sucessfully at %s\n", ctime(&app_ctx.time_ctx.tv));

CleanUp:
				/* disconnect to server and cleanup work */
				mosquitto_disconnect(app_ctx.mqtt_ctx.mosq);
				mosquitto_destroy(app_ctx.mqtt_ctx.mosq);
				mosquitto_lib_cleanup();
				continue;			

			 }

		} //else

	} // while(1)

}

int  print_client_usage(char *progname)
{
	printf("******************* %s usage ********************\n\n", progname);
	printf("@ %s usage: \n\n", progname);
	printf("@ -t(--time): specify sampling interval\n\n");
	printf("@ -p(--platform): change the specify platform\n\n  # 1 : 阿里云\n  # 2 : 腾讯云\n  # 3 : 华为云 \n\n");
	printf("@ -d(--deamon): running in the background\n\n");
	printf("@ -h(--help): printf this help information.\n\n");
	printf ("******************* end *************************\n\n");
	return 1;
}

